package com.ddwl.funds.controller;

/**
 * 类PayController.java的实现描述：订单支付接口
 *
 * @author zach
 * @Date :2020-09-24 15:46.
 */

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.ddwl.common.annotation.Auth;
import com.ddwl.common.annotation.Submit;
import com.ddwl.common.constant.BaseEnum;
import com.ddwl.common.controller.BaseController;
import com.ddwl.funds.dao.model.ByteDancePay;
import com.ddwl.funds.service.AliPayServer;
import com.ddwl.funds.service.ByteDanceServer;
import com.ddwl.funds.service.PaymentServer;
import com.ddwl.funds.service.WxPayServer;
import com.ddwl.schema.bo.funds.ByteDancePayNotifyBo;
import com.ddwl.schema.bo.funds.ByteDanceRefundNotifyBo;
import com.ddwl.schema.bo.funds.FundsPaymentBo;
import com.ddwl.schema.bo.funds.WxEntPayBo;
import com.ddwl.schema.vo.base.RestVo;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
@RestController
@Api(tags = "支付订单相关API",hidden = true)
public class PayController extends BaseController {

    @Resource
    private PaymentServer orderPayServer;
    @Resource
    private WxPayServer wxPayServer;
    @Resource
    private AliPayServer aliPayServer;
    @Resource
    private ByteDanceServer byteDanceServer;

    @Submit
    @PostMapping("/payment")
    @Auth(product = {BaseEnum.ProductEnum.MALL,BaseEnum.ProductEnum.FENXIAO,BaseEnum.ProductEnum.API})
    @ApiOperation("资金支付入口")
    public RestVo<String> wxAppPrepay(@RequestBody FundsPaymentBo paymentBo) {
        if(!BaseEnum.ProductEnum.API.getName().equals(getProduct())){
            fillBaseField(paymentBo);
        }
        return RestVo.ok(orderPayServer.wxpay(paymentBo));
    }

    @Submit
    @PostMapping("/aliAppPrepay")
    @Auth(product = {BaseEnum.ProductEnum.FENXIAO})
    @ApiOperation("支付宝app支付入口")
    public RestVo<String> prepay(@RequestParam String orderId) {
        return RestVo.ok(null);
    }

    @Submit
    @PostMapping("/dataCorrection")
    @ApiOperation("主动查询通知微信支付状态")
    public RestVo dataCorrection(@RequestParam String orderId) {
        wxPayServer.queryWxPayStatus(orderId);
        return RestVo.ok(null);
    }

    @Submit
    @PostMapping("/getRefundNotify")
    @ApiOperation("主动查询退款状态并通知业务")
    public RestVo getRefundNotify(@RequestParam String bizRefundsNo) {
        return RestVo.ok( orderPayServer.getRefundNotify(bizRefundsNo));
    }

    @Submit
    @PostMapping("/wxDataCorrection")
    @ApiOperation("微信旧订单数据订正")
    public RestVo<String> wxDataCorrection() {
        return RestVo.ok(wxPayServer.dataCorrection());
    }

    @Submit
    @ApiOperation(value = "微信支付回调通知处理")
    @PostMapping("/wx/{appId}/notify")
    public String parseOrderNotifyResult(@PathVariable String appId, @RequestBody String xmlData) throws WxPayException {
        WxPayOrderNotifyResult notifyResult = wxPayServer.getWxPayServer(appId).parseOrderNotifyResult(xmlData);
        log.info("===========收到微信支付回调 notifyResult={}",JSON.toJSONString(notifyResult));
        wxPayServer.wxPayNotify(notifyResult);
        return WxPayNotifyResponse.success("成功");
    }

    @Submit
    @ApiOperation(value = "微信退款回调通知处理")
    @PostMapping("/wx/{appId}/refundsNotify")
    public String refundsNotify(@PathVariable String appId, @RequestBody String xmlData) throws WxPayException {
        WxPayRefundNotifyResult notifyResult = wxPayServer.getWxPayServer(appId).parseRefundNotifyResult(xmlData);
        log.info("===========收到微信退款回调 notifyResult={}",JSON.toJSONString(notifyResult));
        wxPayServer.wxRefundNotify(notifyResult);
        return WxPayNotifyResponse.success("成功");
    }

    @Submit
    @ApiOperation(value = "支付宝支付完成回调",hidden = true)
    @PostMapping("/alipay/payNotify")
    public String refundsNotify(HttpServletRequest httpServletRequest) throws AlipayApiException {
        log.info("==================支付宝异步返回支付结果开始 ");
        Map aliParams = httpServletRequest.getParameterMap();
        Map<String, String> conversionParams = new HashMap<String, String>();
        for (Iterator iter = aliParams.keySet().iterator(); iter.hasNext(); ) {
            String key = (String)iter.next();
            String[] values = (String[]) aliParams.get(key);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            conversionParams.put(key, valueStr);
        }
        log.info("==================回调参数集合：mapJson={}" , JSON.toJSONString(conversionParams));
        return  aliPayServer.payNotify(conversionParams);
    }

    @Submit
    @ApiOperation(value = "付款到零钱/银行卡", hidden = true)
    @PostMapping("/wx/entPay")
    @Auth(product = BaseEnum.ProductEnum.API)
    public RestVo entPay(@Valid @RequestBody WxEntPayBo bo){
        wxPayServer.entPay(bo);
        return RestVo.ok();
    }

    @Submit
    @ApiOperation(value = "字节跳动支付回调通知处理")
    @PostMapping("/byteDance/notify")
    public String byteDancePayNotify(@Valid @RequestBody String notifyStr) {
        return byteDanceServer.byteDancePayNotify(notifyStr);
    }

    @Submit
    @ApiOperation(value = "字节跳动订单查询")
    @PostMapping("/byteDance/queryOrder")
    @Auth(product = BaseEnum.ProductEnum.BYTE_DANCE)
    public RestVo<ByteDancePay> queryOrder(@RequestParam String orderId) {
        return RestVo.ok(byteDanceServer.queryOrder(orderId));
    }

    @Submit
    @ApiOperation(value = "字节跳动退款回调通知处理")
    @PostMapping("/byteDance/refundNotify")
    public String byteDanceRefundNotify(@Valid @RequestBody String notifyStr) {
        return byteDanceServer.byteDanceRefundNotify(notifyStr);
    }

}
